﻿using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using EpiNEXT.Core;

namespace EpiNEXT.Data
{
    /// <summary>
    /// Abstract data type for databases
    /// </summary>
    public interface IDbDriver
    {
        #region Properties
        /// <summary>
        /// The connection string to the database.
        /// </summary>
        string ConnectionString { get; }

        /// <summary>
        /// The progress of a save or load operation
        /// </summary>
        double ProcessingProgress { get; }

        /// <summary>
        /// Whether or not the data driver is processing (e.g. saving records)
        /// </summary>
        bool IsProcessing { get; }
        #endregion // Properties

        #region Methods
        /// <summary>
        /// Identifies the database
        /// </summary>
        string IdentifyDatabase();

        /// <summary>
        /// Saves a record to the database
        /// </summary>
        bool SaveRecord(Form form, Record record);

        /// <summary>
        /// Saves a record to the database asynchronously
        /// </summary>
        Task<bool> SaveRecordAsync(Form form, Record record);

        /// <summary>
        /// Physically removes a record from the database
        /// </summary>
        bool DeleteRecord(Form form, Record record);

        /// <summary>
        /// Soft-deletes a record from the database (setting record status to 0)
        /// </summary>
        bool SoftDeleteRecord(Form form, Record record);

        /// <summary>
        /// Populates the collection of records for the specified form directly from the database
        /// </summary>
        void PopulateRecordCollection(DataEntryInstrument form);

        /// <summary>
        /// Gets an observable collection of records from a table in the database
        /// </summary>
        ObservableCollection<Record> GetRecordCollection(string tableName);

        /// <summary>
        /// Saves all records in all the forms in the specified project to the database
        /// </summary>
        /// <param name="project">The project whose records should be saved to disk</param>
        /// <returns>bool; whether the operation was successful</returns>
        bool SaveAllRecords(Project project);

        /// <summary>
        /// Saves asynchronously all records in all the forms in the specified project to the database
        /// </summary>
        /// <param name="project">The project whose records should be saved to disk</param>
        /// <returns>bool; whether the operation was successful</returns>
        Task<bool> SaveAllRecordsAsync(Project project);
        #endregion // Methods
    }
}
